#ifndef __DRV_SD_H__
#define __DRV_SD_H__

#include "app_config.h"
#include "Type_def.h"

#if TCFG_DRV_SD_CARD_SPI_SUPPORT
/**
 * CID  CMD2  CMD10
 * CSD  CMD9
 * OCR  CMD58
 * RCA  CMD3
 * 
 * 
 * 
 * 
 * IF_COND CMD8
 * OP_COND ACMD41
 * 
 * MMC Card  CMD1 IF_COND
*/

#if 0
SDSC Card 可以通过CMD16命令设置Block length
SDHC和SDXC Cards block length fixed to 512 Bytes;
SDUC卡 不支持SPI模式
#endif

#define DUMMY_BYTE				 0xFF 
#define SD_BLOCKSIZE			 512

//CMD定义
#define CMD0_GO_IDLE_STATE      0       // - 卡复位  Resets all cards to idle state
#define CMD1                    1       // MMC 复位
#define CMD2_ALL_SEND_CID       2       // R2 Asks any card to send the CID numbers on the CMD line (any card that is connected to the host will respond)
#define CMD3_SEND_RELATIVE_ADDR 3       // R6 Ask the card to publish a new relative address (RCA)
#define CMD4_SET_DSR            4       // - Programs the DSR of all cards
#define CMD5                    5       // - 保留 reserved for I/O cards (refer to the "SDIO Card Specification")
#define CMD7_SELECT_DESELECT_CARD   7   // R1b
#define CMD8_SEND_IF_COND       8       // R7 命令8 ，SEND_IF_COND  Send Interface Condition Command
#define CMD9_SEND_CSD           9       // R2 命令9 ，读CSD数据
#define CMD10_SEND_CID          10      // R2 命令10，读CID数据
#define CMD11                   11      // 保留
#define CMD12_STOP_TRANSMISSION   12      // R1b 命令12，停止数据传输
#define CMD13_SEND_STATUS         13    // R2 
#define CMD14                   14  // 保留
#define CMD15_GO_INACTIVE_STATE 15      // - 
#define CMD16_SET_BLOCKLEN      16      // R1 命令16，设置SectorSize 应返回0x00
#define CMD17_READ_SINGLE_BLOCK   17      // R1 命令17，读sector
#define CMD18_READ_MULTIPLE_BLOCK   18      // R1 命令18，读Multi sector
// CMD19 ~ CMD23 
#define CMD23   23      //命令23，设置多sector写入前预先擦除N个block
#define CMD24_WRITE_SINGLE_BLOCK   24      // R1 命令24，写sector
#define CMD25_WRITE_MULTIPLE_BLOCK   25      // R1 命令25，写Multi sector
#define CMD26                   26// 保留
#define CMD27_PROGRAM_CSD       27  // R1
#define CMD28_SET_WRITE_PORT    28  // R1b
#define CMD29_CLR_WRITE_PORT    29  // R1b
#define CMD30_SEND_WRITE_PORT   30  // R1
#define CMD31   31  // 保留
#define CMD32_ERASE_WR_BLK_START    32 // R1
#define CMD33_ERASE_WR_BLK_END      33  // R1
#define CMD38_ERASE                 38  // R1b

#define CMD41   41      //命令41，应返回0x00
#define CMD55_APP_CMD   55      // R1 命令55，应返回0x01
#define CMD56_GEN_CMD   56      // R1
#define CMD58_READ_OCR   58      //命令58，读OCR信息
#define CMD59   59      //命令59，使能/禁止CRC，应返回0x00

/**<define ACMD index (ACMD6 ~ ACMD51)*/
/**<application specific commands used/reserved by SD memory card*/
#define	ACMD6_SET_BUS_WIDTH			        6  
#define	ACMD13_SD_STATUS			        13 
#define	ACMD22_SEND_NUM_WR_BLOCKS	        22 
#define	ACMD23_SET_WR_BLK_ERASE_COUNT       23 
#define	ACMD41_SD_SEND_OP_COND			    41            /**<The response to ACMD41 is the operation condition register of the card*/
#define	ACMD42_SET_CLR_CARD_DETECT		    42 
#define	ACMD51_SEND_SCR					    51 


#define	VOLTAGE_WINDOWS					0x40FF8000     /**<2.7v~3.6v*/
#define VOLTAGE_PATTERN                 0x000001AA     /**<0x01:2.7-3.6V,0xAA:check pattern,pattern can use any 8-bit*/


//数据写入回应字意义
#define SD_DATA_OK                0x05
#define SD_DATA_CRC_ERROR         0x0B
#define SD_DATA_WRITE_ERROR       0x0D
#define SD_DATA_OTHER_ERROR       0xFF

//SD卡回应标记字
#define SD_RESPONSE_NO_ERROR      0x00
#define SD_IN_IDLE_STATE          0x01
#define SD_ERASE_RESET            0x02
#define SD_ILLEGAL_COMMAND        0x04
#define SD_COM_CRC_ERROR          0x08
#define SD_ERASE_SEQUENCE_ERROR   0x10
#define SD_ADDRESS_ERROR          0x20
#define SD_PARAMETER_ERROR        0x40
#define SD_RESPONSE_FAILURE       0xFF




//SD卡类型
enum {
    E_SDCARD_TYPE_UNKNOW=0,
    E_SDCARD_TYPE_MMC,      // MMC 卡
    E_SDCARD_TYPE_SD_V1,    // SD1.X版本
    E_SDCARD_TYPE_SD_V2,    // SD2.X版本
    E_SDCARD_TYPE_SD_V2HC,  // SD2 HC版本
    E_SDCARD_TYPE_MAX
};

enum {
    E_CSD_VER_1DOT0 = 0,        // SDSC: Standard Capacity
    E_CSD_VER_2DOT0 = 1,        // SDHC: High Capacity and  SDXC:Extended Capacity
    E_CSD_VER_3DOT0 = 2,        // SDUC: Ultra Capacity
    E_CSD_VER_Reserved = 3,     // Reserved
};


struct sd_csd_t {
    uint8_t csd_struct: 2;          // 2 bit[127:126]   
    uint8_t reserved1:  6;          // 6 bit[125:120]

    uint8_t TAAC;                   // 8 bit[119:112]
    uint8_t NSAC;                   // 8 bit[111:104]
    uint8_t TRAN_SPEED;             // 8 bit[103:96]
    
    uint16_t CCC: 12;               // 12 bit[95:84]
    uint16_t READ_BL_LEN: 4;        // 4 bit[83:80]
    
    uint8_t READ_BL_PARTIAL: 1;    // 1 bit[79]
    uint8_t WRITE_BLK_MISALIGN: 1; // 1 bit[78]
    uint8_t READ_BLK_MISALIGN: 1;  // 1 bit[77]
    uint8_t DSR_IMP: 1;            // 1 bit[76]
    uint8_t reserved2:4;           // 6 bit[75:70]

    uint32_t C_SIZE;                // 22 bit[69:48]

    // uint16_t reserved3: 1;       // 1 bit[47]
    uint16_t EARSE_BLK_EN: 1;       // 1 bit[46]
    uint16_t SECTOR_SIZE: 7;        // 7 bit[45:39]
    uint16_t WP_GRP_SIZE: 7;        // 7 bit[38:32]

    uint16_t WP_GRP_ENABLE:1;      // 1 bit[31]
    uint16_t reserved4:2;          // 2 bit[30:29]
    uint16_t R2W_FACTOR:3;         // 3 bit[28:26]
    uint16_t WRITE_BL_LEN:4;       // 4 bit[25:22]
    uint16_t WRITE_BL_PARTIAL:1;   // 1 bit[21]
    uint16_t reserved5:5;          // 5 bit[20:16]

    uint8_t FILE_FORMAT_GRP:1;      // 1 bit[15]
    uint8_t COPY:1;                 // 1
    uint8_t PERM_WRITE_PROTECT:1;   // 1 bit[13]
    uint8_t TMP_WRITE_PROTECT:1;    // 1 bit[12]
    uint8_t FILE_FORMAT:2;          // 2 bit[11:10]
    uint8_t WP_UPC:1;               // 1 bit[9]
    uint8_t reserved6:1;            // 1 bit[8]

    uint8_t CRC:7;                  // 7 bit[7:1]
    uint8_t reserved7:1;            // 1 bit[0]
};

struct sd_cid_t 
{
    uint8_t MID;            // manufacturerID   MID  8bit        127:120
    uint8_t OID[2+1];       // OEM/appliID      OID  16bit       119:104
    uint8_t PNM[5+1];       // product name     PNV  40bit       103:64    
    uint8_t PRV;            // product revision PRV  8bit        63:56
    uint32_t PSN;           // product serial number;   PSN  32bit [55:24]
    // uint8_t reserved1;   // -- 4  [23:20]
    uint16_t MDT;           // manufacturing date;     MDT 12bit[19:8]
    uint8_t CRC;            // CRC7 CheckSum  7 bit[7:1]
    // uint8_t reserved2;   // -- 1bit [0]
};

struct sd_cardinfo_t {

    struct sd_csd_t csd;
    struct sd_cid_t cid;

    uint8_t     card_type;      /* 卡类型 */
    uint32_t    capacity;       /* 卡容量 */
    uint16_t    RCA;            /* 相对地址 */
    uint32_t    block_size;     /* 卡块大小 */
    uint32_t    space_total;    /* 总容量 */ 
    uint32_t    space_free;     /* 可用空间 */
};

uint8_t SD_GPIO_Config(void);

uint8_t SD_Init(void);

unsigned char SD_ReadSingelBlock(unsigned char*buffer, unsigned long address);

unsigned char SD_WriteSingleBlock(unsigned char *buffer, uint32_t address);

unsigned char SD_ReadMultipleBlock(unsigned char *buffer, uint32_t address, uint32_t block_cnt);

unsigned char SD_WriteMultipleBlock(unsigned char *buffer, uint32_t address, uint32_t block_cnt);

unsigned char SD_GetStatus(unsigned char istask);

unsigned char SD_GetCardInfo(void);

void SD_ReadWriteTest();

#endif
#endif